﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Messaging;
using System.Text;
using DTCash.Logger;
using DTCash.Logger.DTO;

namespace Uranus.Common
{
    [Serializable]
    public class SendNoteMessageALLDTO
    {
        /// <summary>
        /// 
        /// </summary>
        public int NoteMessageID { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public int NoteMessageTypeID { set; get; }

        /// <summary>
        /// 
        /// </summary>
        public int NoteMessageUserID { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Mobile { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Email { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public int UserID { get; set; }

        /// <summary>
        /// 内容
        /// </summary>
        public string NoteMessageContent { get; set; }

        /// <summary>
        /// 发送次数
        /// </summary>
        public int SendCount { get; set; }
    }
    /* public class MSMQHelper
     {
         public static string MessageQueue_IP = ConfigurationManager.AppSettings["MessageQueue_IP"];
         public static string MessageQueue_Path = ConfigurationManager.AppSettings["MessageQueue_IP"];
         public MSMQHelper()
         {
             if (!MessageQueue.Exists(MessageQueue_Path))
             {
                 MessageQueue.Create(MessageQueue_Path);
                 MessageQueue mqTemp = new MessageQueue(MessageQueue_Path);
                 mqTemp.SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
             }
         }
         public static void Insert<T>(T entity)
         {
             if (!MessageQueue.Exists(MessageQueue_Path))
             {
                 MessageQueue.Create(MessageQueue_Path);
                 MessageQueue mqTemp = new MessageQueue(MessageQueue_Path);
                 mqTemp.SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
             }
             new MessageQueue(MessageQueue_Path).Send(entity);
         }
     }*/
    /// <summary> 
    /// Message Queue helper class 
    /// </summary> 
    /// <typeparam name= "T "> </typeparam> 
    public class MessageQueueHelper<T> : MarshalByRefObject where T : class, new()
    {
        public static string MessageQueue_IP = ConfigurationManager.AppSettings["MessageQueue_IP"];
        public static string MessageQueue_Path = ConfigurationManager.AppSettings["MessageQueue_Path"];
        //  public static string MessageQueue_LocalPath = ConfigurationManager.AppSettings["MessageQueue_LocalPath"];
        public MessageQueueHelper()
        {

            try
            {
                // string path = isLocalComputer ? MessageQueue_LocalPath : MessageQueue_Path;
                m_AllowException = true;
                //为什么我用代码建？首先MessageQueue.Exists()不支持FormatName Path。其次对于一些权限，在代码中指定可能会有问题，比如说因为操作系统的不同。所以，我的主张，对于MSMQ的应用，事先手工建立好队列比较安全。


                /*  if (MessageQueue.Exists(MessageQueue_Path))
                      m_Msq = new MessageQueue(MessageQueue_Path);
                  else
                  {
                      m_Msq = MessageQueue.Create(MessageQueue_Path);
                      m_Msq.MaximumQueueSize = long.MaxValue;
                 *          m_Msq = MessageQueue.Create(MessageQueue_Path);
                  m_Msq.MaximumQueueSize = long.MaxValue;
                  }*/
                //MSMQQueueInfoClass
                m_Msq = new MessageQueue(MessageQueue_Path);
                //
                //   m_Msq.SetPermissions("Everyone", System.Messaging.MessageQueueAccessRights.FullControl);

                m_Msq.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) });
                //   m_Msq.Label = typeof(T).Name;
                m_Msq.ReceiveCompleted += new ReceiveCompletedEventHandler(Msq_ReceiveCompleted);

                //  sharedModeDenyReceive
            }
            catch (Exception ex)
            {

                LogHelper.WriteLog(LogEnum.Error, "初始化msmq", ex.ToString());
            }
        }
        ~MessageQueueHelper()
        {
            Close();
        }
        private MessageQueue m_Msq;
        private bool m_AllowException;

        public bool AllowException
        {
            get { return m_AllowException; }
            set { m_AllowException = value; }
        }
        private bool MssageQueueReady()
        {
            if (m_Msq == null)
                if (AllowException)
                    throw new Exception("The message queue is not ready. ");
                else
                    return false;
            else
                return true;
        }
        public void Send(object msg)
        {
            try
            {
                if (!msg.GetType().Equals(typeof(T))) return;
                if (!MssageQueueReady()) return;

                Message message = new Message();
                message.Recoverable = true;
                message.Body = msg;
                m_Msq.Send(message);


            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(LogEnum.Error, "加入队列 msmq", ex.ToString());
            }
        }
        public void Send(object msg, string label)
        {
            if (!MssageQueueReady()) return;
            try
            {

                m_Msq.Send(msg, label);
            }
            catch
            {
                // TODO: Send Message queue failed 
            }
        }
        public T Receive()
        {
            if (!MssageQueueReady()) return default(T);
            Message m = m_Msq.Receive(MessageQueueTransactionType.Single);
            return m.Body as T;
        }
        public IList<T> ReceiveAll()
        {
            IList<T> list = new List<T>(); try
            {
                if (!MssageQueueReady()) return null;
                Message[] ms = m_Msq.GetAllMessages();

                foreach (Message m in ms)
                {
                    list.Add(m.Body as T);
                    m_Msq.ReceiveById(m.Id);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(LogEnum.Error, "获取队列 msmq", ex.ToString());
            }
            return list;
        }
        /*   public IList<T> ReceiveAll()
       {
           IList<T> list = new List<T>();
           try
           {
               if (!MssageQueueReady()) return null;
               using (MessageEnumerator messages = m_Msq.GetMessageEnumerator2())
               {
                   while (messages.MoveNext(TimeSpan.FormMinutes(30)))
                   {
                       Message message = message.Current;
                       Cosole.WriteLine(message.Body);
                   }
               }
           }
           catch (Exception ex)
           {
               Uranus.Common.LogHelper.WriteLog(LogEnum.Error, "获取队列 msmq", ex.ToString());
           }
           return list;
       }*/


        public T Peek()
        {
            if (!MssageQueueReady()) return default(T);
            //m_Msq.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) }); 
            Message m = m_Msq.Peek();
            return m.Body as T;
        }
        public void AsynchronismReceive()
        {
            if (!MssageQueueReady()) return;
            m_Msq.BeginReceive();
        }
        public void EndReceive()
        {
            if (!MssageQueueReady()) return;
        }
        private void Msq_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
        {
            MessageQueue mq = (MessageQueue)sender;
            Message m = mq.EndReceive(e.AsyncResult);
            if (ReceiveEvent != null)
                ReceiveEvent(this, new ReceiveEventArgs<T>(m.Body as T));
            mq.BeginReceive();
        }
        public event ReceiveEventHandler ReceiveEvent;
        public delegate void ReceiveEventHandler(object sender, ReceiveEventArgs<T> e);
        public void Close()
        {
            if (m_Msq != null)
                m_Msq.Close();
        }
    }

    public class ReceiveEventArgs<T> : EventArgs where T : class
    {
        public ReceiveEventArgs(T result)
        {
            m_Result = result;
        }
        private T m_Result;

        public T Result
        {
            get { return m_Result; }
            //set { m_Result = value; } 
        }
    }
}
